package com.turtle3d.formallanguage.grammar.parser;

import java.util.ArrayList;

import com.turtle3d.formallanguage.grammar.Production;
import com.turtle3d.formallanguage.symbol.Symbol;
import com.turtle3d.formallanguage.symbol.SymbolClass;
import com.turtle3d.formallanguage.symbol.SymbolFactory;


/**
 * <p>Tools for defining grammars.</p>
 * 
 * @author Marek Paterczyk <marek.paterczyk@gmail.com>
 * 
 */
public abstract class SimpleParser
{
	/**
	 * @param productionString i.e. B->B[-F][+F] F->F(r*1.8)F(r*1.8)
	 * @return
	 */
	public static Production parseProduction(String productionString)
	{
		Production production = new Production();

		String[] sides = productionString.split("->");
		
		String symbolSequence=sides[1];
		for(int i=2;i<sides.length;i++)
			symbolSequence+="->"+sides[i];
		
		if(sides[0].indexOf(':')!=-1){
		String leftSide[] = sides[0].split(":");
			try
			{
				production.setProbability(Float.parseFloat(leftSide[0].trim()));
			}
			catch (NumberFormatException e)
			{
			}
			production.setLeftSide(new Symbol(leftSide[1].trim()));
		}
		else
			production.setLeftSide(new Symbol(sides[0]));
							
		production.setRightSide(parseSymbolClassSequence(symbolSequence));
		return production;

	}
	
	/**
	 * 
	 * @param symbols i.e. B[-F][+F] F->F(r*1.8)F(r*1.8)
	 * @return
	 */
	public static ArrayList<SymbolClass> parseSymbolClassSequence(String symbols){
		
		ArrayList<SymbolClass> symbolClasses = new ArrayList<SymbolClass>();

		for (int i = 0; i < symbols.length(); i++)
		{
			String c = (new Character(symbols.charAt(i))).toString();

			if (i + 1 < symbols.length() && symbols.charAt(i + 1) == '(')
			{
				int pos1 = i + 1;
				int pos2 = symbols.indexOf(')', pos1);
				String symbolClassName = symbols.substring(i, pos2 + 1);
				// App.println(symbolClassName);
				symbolClasses.add(SymbolFactory.getSymbolFactory()
						.getSymbolClass(symbolClassName));

				i = pos2;

			}
			else
			{
				symbolClasses.add(SymbolFactory.getSymbolFactory()
						.getSymbolClass(c));
			}
			
		}
		
		return symbolClasses;
				
	}
	
	public static ArrayList<Symbol> parseSymbolSequence(String symbols){
		return convertClassesToInstances(parseSymbolClassSequence(symbols));
	}
	
	public static ArrayList<Symbol> convertClassesToInstances(ArrayList<SymbolClass> symbolClasses){
		ArrayList<Symbol> symbols = new ArrayList<Symbol>();
		for(SymbolClass c: symbolClasses)
			symbols.add(SymbolFactory.getSymbolFactory().createSymbolofClass(c.getSymbol()));
		
		return symbols;
		
	}

}
